package cn.qihua.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.shiro.authz.permission.WildcardPermission;

import cn.qihua.dao.ISysOrganizationDAO;
import cn.qihua.dao.ISysResourceDAO;
import cn.qihua.dao.ISysRoleDAO;
import cn.qihua.dao.ISysUserDAO;
import cn.qihua.model.SysOrganization;
import cn.qihua.model.SysResource;
import cn.qihua.model.SysRole;
import cn.qihua.model.SysUser;
import cn.qihua.service.ISystemService;

public class SystemService implements ISystemService {
	private ISysOrganizationDAO sysOrganizationDAO;
	private ISysResourceDAO sysResourceDAO;
	private ISysRoleDAO sysRoleDAO;
	private ISysUserDAO sysUserDAO;

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findOrgById(java.lang.Integer)
	 */
	@Override
	public SysOrganization findOrgById(Integer id) {
		return sysOrganizationDAO.findById(id);
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findResById(java.lang.Integer)
	 */
	@Override
	public SysResource findResById(Integer id) {
		return sysResourceDAO.findById(id);
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findRoleById(java.lang.Integer)
	 */
	@Override
	public SysRole findRoleById(Integer id) {
		return sysRoleDAO.findById(id);
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findByParentId(java.lang.Integer)
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<SysOrganization> findByParentId(Integer parentId) {
		return sysOrganizationDAO.findByParentId(parentId);
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#addOrg(cn.qihua.model.SysOrganization)
	 */
	@Override
	public void addOrg(SysOrganization transientInstance) {
		sysOrganizationDAO.save(transientInstance);
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#addRes(cn.qihua.model.SysResource)
	 */
	@Override
	public void addRes(SysResource transientInstance) {
		sysResourceDAO.save(transientInstance);
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#addRole(cn.qihua.model.SysRole)
	 */
	@Override
	public void addRole(SysRole transientInstance) {
		sysRoleDAO.save(transientInstance);
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#delOrg(java.lang.Integer)
	 */
	@Override
	public boolean delOrg(Integer id) {
		SysOrganization org = sysOrganizationDAO.findById(id);
		if (org != null) {
			sysOrganizationDAO.delete(org);
			return true;
		} else {
			return false;
		}
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#delRes(java.lang.Integer)
	 */
	@Override
	public boolean delRes(Integer id) {
		SysResource res = sysResourceDAO.findById(id);
		if (res != null) {
			sysResourceDAO.delete(res);
			return true;
		} else {
			return false;
		}
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#delRole(java.lang.Integer)
	 */
	@Override
	public boolean delRole(Integer id) {
		SysRole role = sysRoleDAO.findById(id);
		if (role != null) {
			sysRoleDAO.delete(role);
			return true;
		} else {
			return false;
		}
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findAllOrg()
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<SysOrganization> findAllOrg() {
		return sysOrganizationDAO.findAll();
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findAllRes()
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<SysResource> findAllRes() {
		return sysResourceDAO.findAll();
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findAllRole()
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<SysRole> findAllRole() {
		return sysRoleDAO.findAll();
	}

	// 根据角色编号得到角色标识符列表
	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findRoles(java.util.List)
	 */
	@Override
	public Set<String> findRoles(List<Integer> list) {
		Set<String> roles = new HashSet<String>();
		for (Integer roleId : list) {
			SysRole role = findRoleById(roleId);
			if (role != null) {
				roles.add(role.getText());
			}
		}
		return roles;
	}

	// 根据角色编号得到权限字符串列表
	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findPermissionsByRole(java.util.List)
	 */
	@Override
	public Set<String> findPermissionsByRole(List<Integer> list) {
		Set<Integer> resourceIds = new HashSet<Integer>();
		for (Integer roleId : list) {
			SysRole role = findRoleById(roleId);
			if (role != null) {
				resourceIds.addAll(role.getListResourceIds());
			}
		}
		return findPermissionsByRes(resourceIds);
	}
	// 得到资源对应的权限字符串
	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findPermissionsByRes(java.util.Set)
	 */
	@Override
	public Set<String> findPermissionsByRes(Set<Integer> resourceIds) {
		Set<String> permissions = new HashSet<String>();
		for (Integer resourceId : resourceIds) {
			SysResource resource = findResById(resourceId);
			if (resource != null && !resource.getPermission().isEmpty()) {
				permissions.add(resource.getPermission());
			}
		}
		return permissions;
	}
	// 根据用户权限得到菜单
	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findMenus(java.util.Set)
	 */
	@Override
	public List<SysResource> findMenus(Set<String> permissions) {
		List<SysResource> allResources = findAllRes();
		List<SysResource> menus = new ArrayList<SysResource>();
		for (SysResource resource : allResources) {
			if (resource.isRootNode()) {
				continue;
			}
			// if (resource.getType() != Resource.ResourceType.menu) {
			// continue;
			// }
			if (!hasPermission(permissions, resource)) {
				continue;
			}
			menus.add(resource);
		}
		return menus;
	}
	 /* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findRolesByUId(int)
	 */
    @Override
	public Set<String> findRolesByUName(String username) {
        SysUser user = sysUserDAO.findByUsername(username);
        if(user == null) {
            return Collections.emptySet();
        }
        return findRoles(user.getListRoleIds());
    }

    /* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#findPermissionsByUId(int)
	 */
    @Override
	public Set<String> findPermissionsByUName(String username) {
    	SysUser user = sysUserDAO.findByUsername(username);
        if(user == null) {
            return Collections.emptySet();
        }
        return findPermissionsByRole(user.getListRoleIds());
    }

	// 检查是否有权限
	private boolean hasPermission(Set<String> permissions, SysResource resource) {
		if (resource.getPermission().isEmpty()
				|| resource.getPermission().equals("")) {
			return true;
		}
		for (String permission : permissions) {
			WildcardPermission p1 = new WildcardPermission(permission);
			WildcardPermission p2 = new WildcardPermission(
					resource.getPermission());
			if (p1.implies(p2) || p2.implies(p1)) {
				return true;
			}
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#setSysOrganizationDAO(cn.qihua.dao.ISysOrganizationDAO)
	 */
	@Override
	public void setSysOrganizationDAO(ISysOrganizationDAO sysOrganizationDAO) {
		this.sysOrganizationDAO = sysOrganizationDAO;
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#setSysResourceDAO(cn.qihua.dao.ISysResourceDAO)
	 */
	@Override
	public void setSysResourceDAO(ISysResourceDAO sysResourceDAO) {
		this.sysResourceDAO = sysResourceDAO;
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#setSysRoleDAO(cn.qihua.dao.ISysRoleDAO)
	 */
	@Override
	public void setSysRoleDAO(ISysRoleDAO sysRoleDAO) {
		this.sysRoleDAO = sysRoleDAO;
	}

	/* (non-Javadoc)
	 * @see cn.qihua.service.impl.ISystemService#setSysUserDAO(cn.qihua.dao.ISysUserDAO)
	 */
	@Override
	public void setSysUserDAO(ISysUserDAO sysUserDAO) {
		this.sysUserDAO = sysUserDAO;
	}
}
